#include <SDL/SDL.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <iostream>
#include "d_Light.h"
#include "MRMesh.h"
#include "d_Math.h"
#include "camera.h"

#define SWIDTH 640
#define SHEIGHT 480

using namespace std;

SDL_Surface *screen;
MRMesh *mr_mesh;
float angle=0;
Camera camera;
bool toggle_pads = false;
bool toggle_mr = true;
bool toggle_psmooth = true;
bool toggle_lighting = false;
d_Light *light_0;

int target_fps = 30;

void initGL(int w, int h)
{
	camera.SetDimensions(SWIDTH, SHEIGHT);
	camera.SetViewport(0,0,SWIDTH, SHEIGHT);
	camera.SetPerspective(45, 1, 10000);
    camera.SetDistance(400);
	camera.ApplyViewport();
	camera.ApplyPerspective();

	light_0 = new d_Light(GL_LIGHT1);
    light_0->setPosition(0,0,0,1);
	light_0->setAmbient(0.7, 0.7, 0.7, 1);
	light_0->setDiffuse(0.4, 0.4, 0.4, 1);
	light_0->applyProperties();

	glEnable(GL_POINT_SMOOTH);
	glEnable(GL_DEPTH);
	glEnable(GL_DEPTH_TEST);
	glEnable(GL_COLOR_MATERIAL);
	glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
}
bool gMousePressed = false;
void mouseFunc(int button, int state, int x, int y)
{
	
	if (state == SDL_MOUSEBUTTONDOWN)
	{
		gMousePressed = true;
		
		switch (button)
		{
		case SDL_BUTTON_LEFT:
			camera.MouseClick(Camera::LEFT, x, y);
			break;
		case SDL_BUTTON_MIDDLE:
			camera.MouseClick(Camera::MIDDLE, x, y);
			break;
		case SDL_BUTTON_RIGHT:
			camera.MouseClick(Camera::RIGHT, x,y);
		default:
			break;
		}                       
	}
	else
	{
		camera.MouseRelease(x,y);
		gMousePressed = false;
	}
}

void motionFunc(int x, int y)
{
	camera.MouseDrag(x,y);        
}

void drawAxis()
{
	glBegin(GL_LINES);
		glColor3f(1,0,0);
		glVertex3f(0,0,0);
		glVertex3f(10,0,0);
		glColor3f(0,1,0);
		glVertex3f(0,0,0);
		glVertex3f(0,10,0);
		glColor3f(0,0,1);
		glVertex3f(0,0,0);
		glVertex3f(0,0,10);
	glEnd();
}

int d_draw =0;

void drawScene()
{
	////////////FPS Calculation/////////////
    static GLint T0     = 0;
    static GLint Frames = 0;
	static GLfloat seconds;
	static GLfloat fps=0;
	Frames++;
	GLint t = SDL_GetTicks();
	if (t - T0 >= 2000) 
	{
	    seconds = (t - T0) / 1000.0;
	    fps = Frames / seconds;
	    cout << fps << endl;
	    T0 = t;
	    Frames = 0;
	}
	///////////////////////////////////////////////////

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glClearColor(0,0,0,1);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
    camera.ApplyModelview();

	if(toggle_mr)
		//mr_mesh->draw(target_fps, camera);
		mr_mesh->draw(camera);
		//mr_mesh->draw();

	SDL_GL_SwapBuffers();
}

int main(int argv, char **argc)
{
	SDL_Init(SDL_INIT_VIDEO);
	screen = SDL_SetVideoMode(SWIDTH, SHEIGHT, 24, SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWSURFACE);

	initGL(640,480);

	chdir("/home/carlosad/Projects/Part_2/input/cignoni/");

	int start_prep = SDL_GetTicks();
	mr_mesh = new MRMesh("output.pads");
	cout << "Preprocess time: " << (float)(SDL_GetTicks()-start_prep)/1000.0 << endl;
    camera.SetCenter(mr_mesh->get_center());

	SDL_Event event;
	while(1)
	{
		while(SDL_PollEvent(&event))
		{
			if(event.type == SDL_KEYDOWN)
			{
				switch(event.key.keysym.sym)
				{
				case SDLK_ESCAPE:
					SDL_Quit();
					return 0;
				case SDLK_UP:
					mr_mesh->depth_change(1);
					break;
				case SDLK_DOWN:
					mr_mesh->depth_change(-1);
					break;
				case SDLK_p:
					if(toggle_pads)
						toggle_pads = false;
					else
						toggle_pads = true;
					break;
				case SDLK_PAGEUP:
					target_fps+=5;
					cout << "New Target FPS: " << target_fps << endl;
					break;
				case SDLK_PAGEDOWN:
					target_fps-=5;
					cout << "New Target FPS: " << target_fps << endl;
					break;
				case SDLK_s:
					if(toggle_psmooth)
					{
						glDisable(GL_POINT_SMOOTH);
						toggle_psmooth = false;
					}
					else
					{
						glEnable(GL_POINT_SMOOTH);
						toggle_psmooth = true;
					}
					break;
				case SDLK_l:
					if(toggle_lighting)
					{
						glDisable(GL_LIGHTING);
						toggle_lighting = false;
					}
					else
					{
						glEnable(GL_LIGHTING);
						toggle_lighting = true;
					}
					break;
				case SDLK_m:
					if(toggle_mr)
						toggle_mr = false;
					else
						toggle_mr = true;
				}
			}
			if(event.type== SDL_MOUSEBUTTONDOWN)
				mouseFunc(event.button.button, SDL_MOUSEBUTTONDOWN, event.motion.x, event.motion.y);
			if(event.type == SDL_MOUSEBUTTONUP)
				mouseFunc(event.button.button, SDL_MOUSEBUTTONUP, event.motion.x, event.motion.y);
			if(event.type == SDL_MOUSEMOTION)
				motionFunc(event.motion.x, event.motion.y);
		}
		drawScene();
	}
}
